package leetcode;

/**
 * @author caifangyi
 * @date 2022/7/19
 */

import java.util.ArrayList;
import java.util.List;

/**
 * 我的日程安排表 II
 * 
 * 实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内不会导致三重预订时，则可以存储这个新的日程安排。
 *
 * MyCalendar 有一个 book(int start, int end)方法。它意味着在 start 到 end 时间内增加一个日程安排，注意，这里的时间是半开区间，即 [start, end), 实数x 的范围为， start <= x < end。
 *
 * 当三个日程安排有一些时间上的交叉时（例如三个日程安排都在同一时间内），就会产生三重预订。
 *
 * 每次调用 MyCalendar.book方法时，如果可以将日程安排成功添加到日历中而不会导致三重预订，返回 true。否则，返回 false 并且不要将该日程安排添加到日历中。
 *
 * 请按照以下步骤调用MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)
 *
 * 
 *
 * 示例：
 *
 * MyCalendar();
 * MyCalendar.book(10, 20); // returns true
 * MyCalendar.book(50, 60); // returns true
 * MyCalendar.book(10, 40); // returns true
 * MyCalendar.book(5, 15); // returns false
 * MyCalendar.book(5, 10); // returns true
 * MyCalendar.book(25, 55); // returns true
 * 解释： 
 * 前两个日程安排可以添加至日历中。 第三个日程安排会导致双重预订，但可以添加至日历中。
 * 第四个日程安排活动（5,15）不能添加至日历中，因为它会导致三重预订。
 * 第五个日程安排（5,10）可以添加至日历中，因为它未使用已经双重预订的时间10。
 * 第六个日程安排（25,55）可以添加至日历中，因为时间 [25,40] 将和第三个日程安排双重预订；
 * 时间 [40,50] 将单独预订，时间 [50,55）将和第二个日程安排双重预订。
 * 
 *
 * 提示：
 *
 * 每个测试用例，调用MyCalendar.book函数最多不超过1000次。
 * 调用函数MyCalendar.book(start, end)时，start 和end 的取值范围为[0, 10^9]。
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/my-calendar-ii
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

class Day0731 {

    public static void main(String[] args) {

        MyCalendarTwo myCalendarTwo = new MyCalendarTwo();
        boolean book = myCalendarTwo.book(10, 20);// returns true
        boolean book1 = myCalendarTwo.book(50, 60);// returns true
        boolean book2 = myCalendarTwo.book(10, 40); // returns true
        boolean book3 = myCalendarTwo.book(5, 15); // returns false
        boolean book4 = myCalendarTwo.book(5, 10); // returns true
        boolean book5 = myCalendarTwo.book(25, 55); // returns true
        System.out.println(book+":"+
                book1+":"+
                book2+":"+
                book3+":"+
                book4+":"+
                book5
                );
    }

    static class MyCalendarTwo {

        private List<int[]> books = new ArrayList<>();
        private List<int[]> overlaps = new ArrayList<>();
        public MyCalendarTwo() {

        }

        public boolean book(int start, int end) {
            //先判断是否有重合区域
            for (int[] overlap : overlaps) {
                int l = overlap[0];
                int r = overlap[1];
                if(end > l && start < r){
                    return false;
                }
            }

            for (int[] book : books) {
                int l = book[0];
                int r = book[1];
                if(end > l && start < r){
                    overlaps.add(new int[]{Math.max(l,start),Math.min(r,end)});
                }
            }
            books.add(new int[]{start, end});
            return true;
        }
    }


}
